package com.lijiajia.cloud.resource.sys.service.numberid;

import io.lettuce.core.RedisException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

/**
 * redis 实现 数字id服务
 *
 * @author lijiajia
 * @since 2019-05-24
 */
@Slf4j
@Service
public class RedisNumberIdService implements NumberIdService {
    public static final String KEY_PREFIX = "number_id:";
    public static final String KEY_VALUE = KEY_PREFIX + "%s:value";
    public static final String KEY_INCREMENT_VALUE = KEY_PREFIX + "%s:increment_value";
    private RedisTemplate<String, Long> redisTemplate;

    public RedisNumberIdService(RedisTemplate<String, Long> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Override
    public Number get(String name) {
        try {
            return redisTemplate.opsForValue().increment(String.format(KEY_VALUE, name), getIncrement(name));
        } catch (RuntimeException ex) {
            log.debug("redis连接异常", ex);
            return null;
        }
    }

    @Override
    public String get(String name, String prefix) {
        return get(name, prefix, null);
    }

    @Override
    public String get(String name, String prefix, String suffix) {
        prefix = prefix == null ? "" : prefix;
        suffix = suffix == null ? "" : suffix;
        return prefix + get(name) + suffix;
    }

    @Override
    public void setValue(String name, Number value) {
        try {
            redisTemplate.opsForValue().set(String.format(KEY_VALUE, name), value.longValue());
        } catch (RedisException ex) {
            log.warn("redis连接异常", ex);
        }
    }

    @Override
    public void setIncrement(String name, Number increment) {
        assert increment != null;
        try {
            redisTemplate.opsForValue().set(String.format(KEY_INCREMENT_VALUE, name), increment.longValue());
        } catch (RedisException ex) {
            log.warn("redis连接异常", ex);
        }
    }

    private long getIncrement(String name) {
        Long increment = redisTemplate.opsForValue().get(String.format(KEY_INCREMENT_VALUE, name));
        if (increment == null) {
            increment = 1L;
            redisTemplate.opsForValue().set(String.format(KEY_INCREMENT_VALUE, name), 1L);
        }
        return increment;
    }
}
